interface StorageData<T> {
    value: T
    expires?: number // 过期时间戳
}

/**
 * * 存储本地会话数据
 * @param k 键名
 * @param v 键值（无需stringify）
 * @param expire 过期时间（秒）
 */
export const setLocalStorage = <T>(k: string, v: T, expire?: number) => {
    const data: StorageData<T> = {
        value: v,
        expires: expire ? Date.now() + expire * 1000 : undefined // 计算过期时间（毫秒）
    }
    try {
        window.localStorage.setItem(k, JSON.stringify(data))
    } catch (error) {
        return false
    }
}

/**
 * * 获取本地会话数据
 * @param k 键名
 * @returns any
 */
export const getLocalStorage = (k: string) => {
    const item = window.localStorage.getItem(k)
    if (!item) return null
    try {
        const data: StorageData<any> = JSON.parse(item)
        // 如果存在过期时间且当前时间已超过过期时间，则返回 null
        if (data.expires && Date.now() > data.expires) {
            clearLocalStorage(k)
            return null
        }
        return data.value
    } catch (err) {
        return null
    }
}

/**
 * * 清除本地会话数据
 * @param name
 */
export const clearLocalStorage = (name: string) => {
    window.localStorage.removeItem(name)
}

/**
 * * 存储临时会话数据
 * @param k 键名
 * @param v 键值
 * @param expire 过期时间（秒）
 * @returns RemovableRef
 */
export const setSessionStorage = <T>(k: string, v: T, expire?: number) => {
    const data: StorageData<T> = {
        value: v,
        expires: expire ? Date.now() + expire * 1000 : undefined // 计算过期时间（毫秒）
    }
    try {
        window.sessionStorage.setItem(k, JSON.stringify(data))
    } catch (error) {
        return false
    }
}

/**
 * * 获取临时会话数据
 * @returns any
 */
export const getSessionStorage = (k: string) => {
    const item = window.sessionStorage.getItem(k)
    if (!item) return null
    try {
        const data: StorageData<any> = JSON.parse(item)
        // 如果存在过期时间且当前时间已超过过期时间，则返回 null
        if (data.expires && Date.now() > data.expires) {
            clearSessionStorage(k)
            return null
        }
        return data.value
    } catch (err) {
        return null
    }
}

/**
 * * 清除临时会话数据
 * @param name
 */
export const clearSessionStorage = (name: string) => {
    window.sessionStorage.removeItem(name)
}
